package dm.service;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

public class DownloadThread extends Thread
{
	public static final int IMAGE_FILE = 0; 
	public static final int TEXT_FILE = 1;
	
	//common resource
	List<URLObject> urlList = null;
	URLObject urlo;
	String saveIn;
	
	//temp
	String m_folder = "";
	String m_protocolhost = "";
	
	public DownloadThread(URLObject u, List<URLObject> l, String si)
	{
		urlo = u;
		urlList = l;
		saveIn = si;
		
		ThreadLocal<URLObject> localo = new ThreadLocal<URLObject>();
		localo.set(urlo);
		
		urlo.setStatus(URLObject.FINISHED);
		
		m_folder = u.getUrl().substring(0, u.getUrl().lastIndexOf("/"));
		// http://
		if(m_folder.length()>6 && m_folder.indexOf("/", 7)>0)
			m_protocolhost = m_folder.substring(0, m_folder.indexOf("/", 7));
		else
			m_protocolhost = m_folder;
		
		//this.setPriority(MAX_PRIORITY);
		
		//System.out.println("[DownloadThread.Init] " + m_folder + " -- " + saveIn + " -- " + m_protocolhost);
	}
	
	public void run()
	{		
		
		if(urlo.getContentType() == IMAGE_FILE)
			saveImage();
		else
			saveText();
	}
	
	private void saveImage()
	{
		try{
			URL imageUrl = new URL(urlo.getUrl());
        	Image image = Toolkit.getDefaultToolkit().getDefaultToolkit().createImage(imageUrl);
        	
        	File savedFile= new File(urlo.getFileName());
        	
        	boolean hasAlpha = false; //hasAlpha(image);
        	BufferedImage bimage = null;
        	
        	
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha)
            {
            	type = BufferedImage.TYPE_INT_ARGB;
            }
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
            			        	
        	ImageIO.write(bimage,"jpg",savedFile);
		}catch(Exception ex)
		{
			ex.printStackTrace();
		}
	}
	
	private void saveText()
	{
		char[] cbuf = new char[255];
        BufferedReader in = null;
        BufferedWriter out = null;
        
		try{			
			File savedFile= new File(urlo.getFileName());				
			URL url = new URL(urlo.getUrl());
			
	        in = new BufferedReader(new InputStreamReader(url.openStream()));
	        out = new BufferedWriter(new FileWriter(savedFile));
	        
        	//text file
        	while ((in.read(cbuf)) != -1)
	        {
                out.write(cbuf);
            }
        
        
        	out.flush();
        	
        	in.close();
	        out.close();
	        
	        System.out.println("[DownloadThread.saveText]" + urlo.getFileName());
	        
	        //tim cac link moi o day
	        readFromFile(savedFile);
	        //savedFile.
			
		}catch(Exception ex)
		{
			ex.printStackTrace();
		}		
	}
	
	private URLObject isValidURL(String surl)
	{
		URLObject instance = null;
		
		try {
	        // Create a URLConnection object for a URL
			
			//System.out.println("[isValidURL] URL: " + surl + " -- netHost: " + m_protocolhost);
			
	        URL url = new URL(surl);
	        URLConnection conn = url.openConnection();
	        HttpURLConnection hcon = (HttpURLConnection) conn;
	        
	        //Map<String,java.util.List<String>> responseHeader = null;	        
	        //String MIMEtype = null;
	        String charset = null;
	        //Object content = null;
	        URL responseURL = null;
	        
	        String type = null;
	        int length;	        
	        
	        hcon.connect();
	        
	        // Get the response.
	        //responseHeader    = conn.getHeaderFields();
	        
	        responseURL       = conn.getURL( );
	        length  = conn.getContentLength( );
	        type = conn.getContentType( );
	        
	        
	        if ( type != null )
	        {
	        	instance = new URLObject();
	        	
	            String[] parts = type.split( ";" );
	            //MIMEtype = parts[0].trim( );
	            for ( int i = 1; i < parts.length && charset == null; i++ )
	            {
	                String t  = parts[i].trim( );
	                int index = t.toLowerCase( ).indexOf( "charset=" );
	                if ( index != -1 )
	                    charset = t.substring( index+8 );
	            }
	            
	            String host = m_protocolhost.replace("http://", "");
	            //Kiem tra xem url nay co cung website voi trang dau tien hay khong
	            if(!responseURL.getHost().equals(host) && !host.equals(""))
	            {
	            	hcon.disconnect();
	            	return null;
	            }	            
	            
	            String filename = responseURL.getFile().trim();
	            int islash = filename.lastIndexOf('/');
	            
	            if(islash < filename.length()-1)
	            {
	            	filename = filename.substring(islash + 1, filename.length());
	            	filename.replaceAll("/", "");
	            	
	            }	            
	            
	            System.out.println("[isValidURL] Content type: " + type);
	            if(type.indexOf("image")>=0)
	            {
	            	instance.setContentType(DownloadThread.IMAGE_FILE);
	            }
	            else
	            {	
	            	if(filename.trim().equals(""))
	            		filename = filename + "index.html";
	            	else
	            	{
	            		//lay chuoi phia sau dau ?
	            		String rparam = null;
	            		int iq = filename.indexOf('?');
	            		if(iq>=0)
	            		{
	            			//index.htm?id=4556;u=ijn
	            			rparam = filename.substring(iq, filename.length()-1);
	            			rparam = rparam.replaceAll("\\?", "");
	            			rparam = rparam.replaceAll("=", "");
	            			rparam = rparam.replaceAll(";", "");
	            			rparam = rparam.replaceAll(",", "");
	            			
	            			
	            			filename = filename.substring(0, iq);	            			
	            			if(!(filename.endsWith(".htm") || filename.endsWith(".html")))
	            			{
	            				filename = filename.replaceAll(".", "") + rparam+ ".html";
	            			}
	            			else         			
	            				filename = filename.replace(".", rparam + ".");
	            			
	            		}
	            	}
	            		            	
	            	instance.setContentType(DownloadThread.TEXT_FILE);
	            }
	            
	            filename = saveIn + filename;
	            instance.setFileName(filename);
	          //www.tuoitre.com.vn
	            instance.setUrl(responseURL.getProtocol() + "://" + responseURL.getHost() + ""  + responseURL.getFile());
	            instance.setLength(length);
	        }
	        else
	        {
	        	instance = null;	        	
	        }
	        
	        hcon.disconnect();
	        
	        return instance;
	    } catch (StringIndexOutOfBoundsException e)
	    {
	    	System.out.println("[isValidURL] ERROR: " + e.toString());
	    	e.printStackTrace();
	    	return null;
	    }
	    catch(IOException ie)
	    {
	    	ie.printStackTrace();
	    	return null;
	    }
	    catch(NullPointerException ne)
	    {
	    	//System.out.println("[isValidURL] ERROR: " + ne.toString());
	    	ne.printStackTrace();
	    	return null;
	    }
	}
	
	public void readFromFile(File file)
	{		
		try{			
			BufferedReader br = new BufferedReader(new FileReader(file));
			String s = "";
			String stempHREF = "";			
			String stempSRC = "";
			char[] buff = new char[1024];			
			int c;			
			
			while((c=br.read(buff,0,1024))>=0)
			{				
				s = new String(buff, 0, c);
				
				stempHREF = find_href(s, stempHREF);				
				stempSRC = find_src(s, stempSRC);				
			}
			
			br.close();
		}catch(IOException ex)
		{
			ex.printStackTrace();
		}		
	}//end file
	
	private String find_href(String s, String stemp)
	{	
		int t1, t2;
		int j;
		int l = 0;
		String sURL = "";
		
		s = s.replaceAll("<A", "<a");
		s = s.replaceAll("</A>", "</a>");
		s = s.replaceAll(" HREF", " href");
		s = s.replaceAll(" Href", " href");		
				
			
		s = stemp + "" + s;			
		stemp = "";						
		
		
		l = s.length();	
		j = 0;
		while(j<l)
		{			
			t1 = s.indexOf("href", j);
			if(t1>=0)
			{				
				t2 = s.indexOf(">",t1);				
				
				
				j = t2 + 1;
												
				//ket thuc buffer ma chua gap >
				if(t2<0)
				{
					stemp = s.substring(t1, s.length());
					break;							
				}				
				
				sURL = s.substring(t1,t2);
				
				
				t1 = sURL.indexOf("href=\"", 0);
				if(t1>=0)
				{
					if((t2=sURL.indexOf("\"", t1 + 6)) >=0 )
					{
						
						if(countSubString(sURL.substring(t1+1,t2), " ")<=0)
						{
							//System.out.println(sURL.substring(t1,t2+1));
							writeLinkFile(sURL.substring(t1+6,t2));
						}
					}

				}
				else
				{
					//System.out.println(sURL);
					processHREF(sURL);
				}
								
			}
			else
				j++;
		}//end while
		
		if(stemp == "")
		{
			t2 = s.length();
			if(s.substring(t2-1, t2) != " ")
			{
				t1 = s.lastIndexOf(" ");
				if(t1>=0)
					stemp = s.substring(t1, t2);
				
			}
			
		}
		
		return stemp;
	}
	
	private String find_src(String s, String stemp)
	{
		int t1, t2;
		int j;
		int l = 0;
		String sURL = "";
				
		s = s.replaceAll(" SRC", " src");
		s = s.replaceAll(" Src", " src");
		s = s.replaceAll(" src =", " src=");
				
		
		s = stemp + "" + s;
		stemp = "";		
		
		
		l = s.length();	
		j = 0;
		while(j<l)
		{						
			t1 = s.indexOf("src", j);
			if(t1>=0)
			{				
				t2 = s.indexOf(">",t1);				
												
				//ket thuc buffer ma chua gap khoang trang hoac >
				if(t2<0)
				{
					stemp = s.substring(t1, s.length());
					break;							
				}				
									
				j = t2 + 1;								
				
				sURL = s.substring(t1,t2) + "\"";
				t1 = sURL.indexOf("src=\"", 0);
				if(t1>=0)
				{
					if((t2=sURL.indexOf("\"", t1 + 5)) >=0 )
					{
						
						if(countSubString(sURL.substring(t1+1,t2), " ")<=0)
						{
							//System.out.println("[UrlUtil.find_src] " + sURL.substring(t1+5,t2));
							writeLinkFile(sURL.substring(t1+5,t2));
						}			
					}
				}
				else
				{
					//System.out.println(sURL);
					processSRC(sURL);
				}	
				
				//System.out.println(sURL);
				//processSRC(sURL);				
				
			}
			else
				j++;
		}//while
		
		if(stemp == "")
		{
			t2 = s.length();
			if(s.substring(t2-1, t2) != " ")
			{
				t1 = s.lastIndexOf(" ");
				if(t1>=0)
					stemp = s.substring(t1, t2);
			}
			
		}
		
		return stemp;
	}
		
	public static int countSubString(String s1, String s2)
	{
		int i = 0;
		int c = 0;
		int p = s1.indexOf(s2, i);
		
		while( p >=0)
		{
			c++;
			i = p + s2.length();
			
			if(i>=s1.length())
				break;
				
			p = s1.indexOf(s2, i);
		}
		
		return c;
	}
	
	private void writeLinkFile(String slink)
	{
		
		//System.out.println(" [DownloadThread.writeLinkFile] slink " + slink );
		
		int i;
		String folder = m_folder;
		int ish = slink.indexOf('#');
		
		if(ish>=0)
			slink = slink.substring(0, ish);
		
		
		
		if(slink.indexOf("http://") < 0)
		{
			//slink = /somefolder/index.php => host
			//slink = somefolder/index.php => folder
			//slink = ../somefolder/index.php
			
			while(slink.indexOf("../")==0)
			{
				i = folder.lastIndexOf('/');
				folder = folder.substring(0, i);
				slink = slink.replaceFirst("../", "");		
			}
			
			if(slink.trim().indexOf('/') == 0)
			{				
				slink = m_protocolhost + "" + slink;
			}
			else
				slink = folder + "/" + slink;
			
			//System.out.println(" [DownloadThread.writeLinkFile] slink " + slink );
		}
				
		
		if(slink.indexOf("http://") < 0)
			slink = "http://" + slink;
		
		URLObject u = isValidURL(slink);
		
		if(u == null)
		{
			System.out.println(" [DownloadThread.writeLinkFile] slink " + slink );
			return;
		}
		
		System.out.println(" [UrlUtil.writeLinkFile] Link will be added: " + slink);
		
		synchronized(urlList)
		{
			for(i=0; i<urlList.size();i++)
			{
				if(u.getUrl().trim().equals(urlList.get(i).getUrl()))
					return;
			}
		
			
			urlList.add(u);
		}
		
	}
	
	private void processHREF(String s)
	{
		String sToken="href=[\"']*([^\"'#\\s]+)[\"']*";
		Pattern ptRegHref = Pattern.compile(sToken);		
		Matcher matcher = ptRegHref.matcher(s);
		
		while(matcher.find())
		{
			//System.out.println(matcher.group(1));
			writeLinkFile(matcher.group(1));
		}		
	}
	
	private void processSRC(String s)
	{
		String sToken="src=[\"']*([^\"'#\\s]+)[\"']*";
		Pattern ptRegHref = Pattern.compile(sToken);		
		Matcher matcher = ptRegHref.matcher(s);
		
		while(matcher.find())
		{
		
			//System.out.println("[processSRC] " + matcher.group(1));
			writeLinkFile(matcher.group(1));
		
		}		
	}
	
	private boolean hasAlpha(Image image)
	{
        // If buffered image, the color model is readily available
        if (image instanceof BufferedImage)
        {
            BufferedImage bimage = (BufferedImage)image;
            return bimage.getColorModel().hasAlpha();
        }
    
        // Use a pixel grabber to retrieve the image's color model;
        // grabbing a single pixel is usually sufficient
         PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
            pg.grabPixels();
        } catch (InterruptedException e)
        {
        }
    
        // Get the image's color model
        ColorModel cm = pg.getColorModel();
        return cm.hasAlpha();
    }
}
